package com.atom.app.mvvm.ui.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.databinding.ObservableField
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.customview.customView
import com.atom.app.mvvm.*
import com.atom.app.mvvm.abase.BaseKingFragment
import com.atom.app.mvvm.abase.BaseKingViewModel
import com.atom.app.mvvm.databinding.DialogUserInfoBinding
import com.atom.app.mvvm.databinding.FragmentUserBinding
import com.atom.app.mvvm.net.BaseResponse
import com.atom.app.mvvm.net.bean.UpdateUserInfo
import com.atom.app.mvvm.net.bean.UserInfo
import com.atom.app.mvvm.utils.AbstractAdapter
import com.atom.app.mvvm.utils.AbstractViewHolder
import com.atom.app.mvvm.utils.JacksonUtils
import com.atom.module.logger.Logger
import com.atom.module.mvvm.base.view.MVVMDialog
import com.atom.module.mvvm.livedata.SingleLiveData
import com.atom.module.mvvm.livedata.call
import com.atom.module.mvvm.util.Auto
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.ClassicsHeader
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.internal.observers.BlockingBaseObserver
import io.reactivex.rxjava3.schedulers.Schedulers

class UserFragment : BaseKingFragment<FragmentUserBinding, UserViewModel>() {

    override fun initArgs(savedInstanceState: Bundle?) {
        super.initArgs(savedInstanceState)
        Auto.registerTask(this::class) {
            viewModel.getUserInfoList()
            true
        }
    }

    override fun initContentView(
        inflater: LayoutInflater?,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): Int {
        return R.layout.fragment_user
    }

    override fun initViewModel(): UserViewModel {
        return ViewModelProvider(this, VMFactory).get(UserViewModel::class.java)
    }

    override fun initVariableId(): Int {
        return BR.userViewModel
    }

    override fun initViewBinding(binding: FragmentUserBinding, viewModel: UserViewModel) {
        super.initViewBinding(binding, viewModel)
        viewModel.finishRefreshEvent.observe(this) {
            binding.userUpdate.finishRefresh()
        }
        viewModel.data.observe(this) {
            adapter.replaceAll(it)
        }
        // 布局刷新
        binding.userUpdate.setRefreshHeader(ClassicsHeader(requireContext()))
        binding.userUpdate.setRefreshFooter(ClassicsFooter(requireContext()))
        binding.userUpdate.setEnableRefresh(true)
        binding.userUpdate.setEnableLoadMore(false)
        binding.userUpdate.setOnRefreshListener {
            viewModel.getUserInfoList()
        }
        binding.userUpdate.setOnLoadMoreListener { refreshlayout ->
            toastShow("敬请期待")
        }
        // binding.taskUpdate.autoRefresh()
        binding.userList.layoutManager = LinearLayoutManager(requireContext())
        binding.userList.adapter = adapter
    }

    override fun initData(view: View) {
        super.initData(view)
        if (!Auto.startTask(this)) {
            viewModel.getUserInfoList()
        }
    }


    val adapter = object : AbstractAdapter<UserInfo.Data>() {
        override fun getItemViewType(position: Int, data: UserInfo.Data): Int {
            return R.layout.item_user_info
        }

        override fun onCreateViewHolder(
            contentView: View,
            viewType: Int
        ): AbstractViewHolder<UserInfo.Data> {
            return ViewHolder(contentView)
        }
    }

    inner class ViewHolder(v: View) : AbstractViewHolder<UserInfo.Data>(v) {
        override fun onBind(data: UserInfo.Data) {
            view(
                R.id.userName
            ) { t: TextView ->
                t.text = data.fields?.trueName
            }
            view(R.id.account) { t: TextView ->
                t.text = data.pk
            }
            view(R.id.password) { t: TextView ->
                t.text = data.fields?.passWord
            }
            view(R.id.phone) { t: TextView ->
                t.text = data.fields?.phoneNo
            }
            view(R.id.sole) { t: TextView ->
                t.text = data.fields?.role?.fields?.roleName
            }
            view(R.id.edit) { t: TextView ->
                t.setOnClickListener {
                    MVVMDialog<DialogUserInfoBinding, DialogViewModel>(
                        it.context,
                        R.layout.dialog_user_info,
                        DialogViewModel(data),
                        BR.dialogViewModel,
                    ).show { binding, dialogViewModel ->
                        binding.userName.append(data.fields?.trueName)
                        binding.account.append(data.pk)
                        binding.password.append(data.fields?.passWord)
                        binding.phone.append(data.fields?.phoneNo)
                        binding.sole.text = data.fields?.role?.fields?.roleName
                        MaterialDialog(
                            it.context,
                            BottomSheet()
                        ).show {
                            customView(view = binding.root)
                            positiveButton(text = "确定") {
                                dialogViewModel.updateUserInfo() { isSuccess ->
                                    if (isSuccess) {
                                        viewModel.getUserInfoList()
                                    }
                                }
                            }
                            negativeButton(text = "取消")
                        }
                    }
                }
            }
            view(R.id.delete) { t: TextView ->
                t.setOnClickListener {
                    MaterialDialog(it.context).show {
                        title(text = "删除提醒")
                        message(
                            text = """确认删除${data.fields?.trueName}吗?
                                    """.trimIndent()
                        )
                        positiveButton(text = "确认") { dialog ->
                            viewModel.deleteUserInfo(UpdateUserInfo().apply {
                                this.set(data)
                            })
                        }
                        negativeButton(text = "取消") { dialog ->
                            dialog.dismiss()
                        }
                    }
                }
            }
        }
    }
}

class UserViewModel : BaseKingViewModel<AppModel>(AppModel) {

    var finishRefreshEvent: SingleLiveData<Unit> = SingleLiveData()

    val data = SingleLiveData<List<UserInfo.Data>>()

    fun getUserInfoList() {
        addSubscribe(
            model.netApi.getUserInfoList()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(object : BlockingBaseObserver<BaseResponse<List<UserInfo.Data>>>() {
                    override fun onNext(t: BaseResponse<List<UserInfo.Data>>) {
                        if (t.code == 200) {
                            t.data?.also {
                                data.setValue(it)
                            }
                        }
                        finishRefreshEvent.call()
                    }

                    override fun onError(e: Throwable) {
                        Logger.e(e)
                        finishRefreshEvent.call()
                    }
                })
        )
    }

    fun deleteUserInfo(data: UpdateUserInfo) {
        addSubscribe(
            model.netApi.deleteUser(JacksonUtils.objectMapper.writeValueAsString(data))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(object : BlockingBaseObserver<BaseResponse<Unit>>() {
                    override fun onNext(t: BaseResponse<Unit>) {
                        if (t.code == 200) {
                            toast("${t.msg}")
                            getUserInfoList()
                            return
                        }
                        toast("修改失败")
                    }

                    override fun onError(e: Throwable) {
                        Logger.e(e)
                        toast("修改失败")
                    }
                })
        )
    }
}

class DialogViewModel(private val data: UserInfo.Data) : BaseKingViewModel<AppModel>(AppModel) {
    val username = ObservableField<String>()
    val account = ObservableField<String>()
    val password = ObservableField<String>()
    val sole = ObservableField<String>()
    val phone = ObservableField<String>()

    init {
        username.set(data.fields?.trueName)
        account.set(data.pk)
        password.set(data.fields?.passWord)
        phone.set(data.fields?.phoneNo)
        sole.set(data.fields?.role?.fields?.roleName)
    }

    fun updateUserInfo(callback: (Boolean) -> Unit) {
        val apply = UpdateUserInfo().apply {
            this.set(data)
            this.userName = account.get()
            this.passWord = password.get()
            this.trueName = username.get()
            this.phoneNo = phone.get()
        }
        addSubscribe(
            model.netApi.updateUserInfo(JacksonUtils.objectMapper.writeValueAsString(apply))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(object : BlockingBaseObserver<BaseResponse<Unit>>() {
                    override fun onNext(t: BaseResponse<Unit>) {
                        if (t.code == 200) {
                            toast("${t.msg}")
                            callback(true)
                            return
                        }
                        callback(false)
                        toast("修改失败")
                    }

                    override fun onError(e: Throwable) {
                        Logger.e(e)
                        toast("修改失败")
                        callback(false)
                    }
                })
        )
    }

}
